package com.sq.util.web.initer;

import java.lang.reflect.Field;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sq.util.BeanUtil;
import com.sq.util.ClassUtil;
import com.sq.util.DateUtil;
import com.sq.util.StringUtil;
import com.sq.util.exception.CommonException;
import com.sq.util.exception.VisualException;
import com.sq.util.web.validation.ValidInt;
import com.sq.util.web.validation.ValidLong;
import com.sq.util.web.validation.ValidNotEmpty;
import com.sq.util.web.validation.ValidNotNull;
import com.sq.util.web.validation.ValidRegex;
import com.sq.util.web.validation.ValidStringLength;

/**
 * @author sq
 *
 */
public class BaseIniter {

    private static Logger log = LoggerFactory.getLogger(BaseIniter.class);

    static String checkRegex(Field field, String value) {
        ValidRegex validRegex = field.getAnnotation(ValidRegex.class);
        final String name = validRegex.name();
        final boolean canBeNull = validRegex.canBeNull();
        final String defaultValue = validRegex.defaultValue();
        if (value == null) {
            if (canBeNull) {
                return value;
            } else if (StringUtil.isNotBlank(defaultValue)) {
                return defaultValue;
            } else {
                throw new VisualException("提交的参数没有传[{}]或者对应类的参数的ValidRegex没有设置defaultValue", name);
            }
        }
        VisualException.assertNotBlank(value, validRegex.message());
        VisualException.isTrue(value.matches(validRegex.regex()), validRegex.message());
        return value;
    }

    static void setProperty(Class<?> cls, Object instance, Field field, final Object value) throws Exception {
        BeanUtil.setProperty(instance, field, value);
    }

    static void checkNotNull(Field field, Object value) {
        ValidNotNull notNull = field.getAnnotation(ValidNotNull.class);
        VisualException.assertNotNull(value, "[{}]不能为空", notNull.name());
    }

    static void checkStringNotEmpty(Field field, String value) {
        ValidNotEmpty notEmpty = field.getAnnotation(ValidNotEmpty.class);
        VisualException.assertNotBlank(value, "[{}]不能为空字符串", notEmpty.name());
    }

    static Long checkLong(Field field, Long value) {
        ValidLong validLong = field.getAnnotation(ValidLong.class);
        final String name = validLong.name();
        VisualException.isTrue(ClassUtil.isLong(field.getType()), "[{}]类型不是Long", name);
        final long lower = validLong.lower();
        final long upper = validLong.upper();
        final boolean lowerEqual = validLong.lowerEqual();
        final boolean upperEqual = validLong.upperEqual();
        final boolean canBeNull = validLong.canBeNull();
        final String defaultValue = validLong.defaultValue();
        if (value == null) {
            if (canBeNull) {
                return value;
            } else if (StringUtil.isNotBlank(defaultValue)) {
                return new Long(defaultValue);
            } else {
                throw new VisualException("提交的参数没有传[{}]或者对应类的参数的ValidLong没有设置defaultValue", name);
            }
        }
        if (lowerEqual) {
            VisualException.isTrue(value >= lower, "[{}]不能小于[{}]", name, lower);
        } else {
            VisualException.isTrue(value > lower, "[{}]要大于[{}]", name, lower);
        }
        if (upperEqual) {
            VisualException.isTrue(value <= upper, "[{}]不能大于[{}]", name, lower);
        } else {
            VisualException.isTrue(value < upper, "[{}]要小于[{}]", name, lower);
        }
        return value;
    }

    static Integer checkInt(Field field, Integer value) {
        ValidInt validInt = field.getAnnotation(ValidInt.class);
        final String name = validInt.name();
        VisualException.isTrue(ClassUtil.isInt(field.getType()), "[{}]类型不是Integer", name);
        final int lower = validInt.lower();
        final int upper = validInt.upper();
        final boolean lowerEqual = validInt.lowerEqual();
        final boolean upperEqual = validInt.upperEqual();
        final boolean canBeNull = validInt.canBeNull();
        final String defaultValue = validInt.defaultValue();
        if (value == null) {
            if (canBeNull) {
                return value;
            } else if (StringUtil.isNotBlank(defaultValue)) {
                return new Integer(defaultValue);
            } else {
                throw new VisualException("提交的参数没有传[{}]或者对应类的参数的ValidInt没有设置defaultValue", name);
            }
        }
        if (lowerEqual) {
            VisualException.isTrue(value >= lower, "[{}]不能小于[{}]", name, lower);
        } else {
            VisualException.isTrue(value > lower, "[{}]要大于[{}]", name, lower);
        }
        if (upperEqual) {
            VisualException.isTrue(value <= upper, "[{}]不能大于[{}]", name, lower);
        } else {
            VisualException.isTrue(value < upper, "[{}]要小于[{}]", name, lower);
        }
        return value;
    }

    static void checkStringLength(Field field, String value) {
        ValidStringLength range = field.getAnnotation(ValidStringLength.class);
        final String name = range.name();
        final int length = range.length();
        final int lower = range.lower();
        final int upper = range.upper();
        if (StringUtil.isBlank(value)) {
            throw new VisualException("[{}]不能为空", name);
        }
        if (length > 0) {
            if (value.length() != length) {
                throw new VisualException("[{}]位数不等于[{}]", name, length);
            }
        } else {
            if (lower > 0 && value.length() < lower) {
                throw new VisualException("[{}]位数不能小于[{}]", name, lower);
            }
            if (upper > 0 && value.length() > upper) {
                throw new VisualException("[{}]位数不能大于[{}]", name, upper);
            }
        }
    }

    static Object checkLimitLower(Field field, Object value) {
        VisualException.isTrue(ClassUtil.isInt(field.getType()), "属性类型不是Integer");
        Integer v = (Integer) value;
        LimitLower limitLower = field.getAnnotation(LimitLower.class);
        if (v == null || v < limitLower.lower()) {
            v = limitLower.lower();
        }
        return v;
    }

    private static Map<String, DateTimeFormatter> dataFormatterMap = new ConcurrentHashMap<>();

    static Object convert(Field field, String s) {
        try {
            return StringUtil.convert(field.getType(), s);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new VisualException("转换" + s + "为对象的" + field.getName() + "属性类型出错");
        }
    }

    static Object convertToDate(Field field, String s, String format) {
        try {
            if (field.getType().equals(Date.class)) {
                return DateUtil.strToDate(s, format);
            }
            if (field.getType().equals(LocalDate.class)) {
                DateTimeFormatter formatter = dataFormatterMap.get(format);
                return DateUtil.toLocalDate(s, formatter);
            }
            if (field.getType().equals(LocalDateTime.class)) {
                DateTimeFormatter formatter = dataFormatterMap.get(format);
                return DateUtil.toLocalDateTime(s, formatter);
            }
            throw new CommonException("");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new VisualException("转换" + s + "为对象的" + field.getName() + "属性类型出错");
        }
    }

}
